// ConfigMgrLogFile.cpp
// 
// Copyright (c) Jason Sandys, 2009
//
// License: This code is released according to the 
// Microsoft Public License (Ms-PL) as documented at 
// http://osdappchooser.codeplex.com/license
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"

#include "ConfigMgrLogFile.h"

//************************************************************
/**
<summary>The default constructor. Opens a log file and 
determines the time zone offset.</summary>

<param name='lpszComponent'>(in)The name of the component to write
to the log file</param>
*/
//************************************************************
CjConfigMgrLogFile::CjConfigMgrLogFile(LPCTSTR lpszComponent, LPCTSTR lpszLocation)
: m_bFileOpen (false), m_tzOffset (0), m_strComponent (lpszComponent ? lpszComponent : _T ("ConfigMgrGeneric"))
{
	int daylight;	//Indicates whether daylight savings is in effect
	long dstBias;	//The offset if daylight savings is in effect
	
	_tzset();

	//Retrieve the timezone info
	_get_timezone (&m_tzOffset);
	_get_daylight (&daylight);
	_get_dstbias (&dstBias);

	//Adjust the offset if daylight savings is in effect
	if (daylight)
		m_tzOffset += dstBias;

	if (lpszLocation)
		OpenLog (lpszLocation);
}

CjConfigMgrLogFile::~CjConfigMgrLogFile(void)
{
	if (m_bFileOpen)
		Close ();
}

void CjConfigMgrLogFile::OpenLog (LPCTSTR lpszLocation)
{
	CString strTemp, strPath;

	if (lpszLocation)
		strTemp = lpszLocation;

	else
		strTemp.GetEnvironmentVariable (_T ("TEMP"));

	strPath.Format (_T ("%s\\%s.log"), strTemp, m_strComponent);
	
	//Open the specified file for writing in text mode; create it if it doesn't already exist and don't truncate
	m_bFileOpen = (Open (strPath, CFile::modeCreate | CFile::modeWrite | CFile::typeText | CFile::modeNoTruncate) == TRUE);

	if (m_bFileOpen)
	{
		//Go to the end of the log to begin writing
		SeekToEnd ();
	}

}

//************************************************************
/**
<summary>Prepares a message for the log file
</summary>

<param name='type'>(in)The type of message to log (Info, Warning,
or Error)</param>
<param name='nThreadID'>(in)The thread id of the thread initating
the log message</param>
<param name='lpszFile'>(in)The filename of the source code file
initiating the message</param>
<param name='nLineNum'>(in)The line number in the source code
initiaing the message</param>
<param name='dwStrID'>(in)The resource string ID of the message to
write</param>*/
//************************************************************
void CjConfigMgrLogFile::LogMsg (CjConfigMgrLogFile::MsgType type, long nThreadID, LPCTSTR lpszFile, int nLineNum, DWORD dwStrID, ...)
{
	if (m_bFileOpen)
	{
		va_list args;
		va_start(args, dwStrID);

		LogMsg (type, nThreadID, lpszFile, nLineNum, FormatResourceString(dwStrID, &args));

		va_end(args);

	}
}

//************************************************************
/**
<summary>Write a ConfigMgr specific message to the log file
</summary>

<param name='type'>(in)The type of message to log (Info, Warning,
or Error)</param>
<param name='nThreadID'>(in)The thread id of the thread initating
the log message</param>
<param name='lpszFile'>(in)The filename of the source code file
initiating the message</param>
<param name='nLineNum'>(in)The line number in the source code
initiaing the message</param>
<param name='lpszMsg'>(in)The actual message to write to the log
</param>*/
//************************************************************
void CjConfigMgrLogFile::LogMsg (CjConfigMgrLogFile::MsgType type, long nThreadID, LPCTSTR lpszFile, int nLineNum, LPCTSTR lpszMsg)
{
	if (m_bFileOpen)
	{
		CString strTemp = lpszMsg;

		strTemp.Replace (_T('\n'), _T(' '));
		CTime t = CTime::GetCurrentTime();

		WriteString (_T ("<![LOG["));	
		WriteString (strTemp);	
		WriteString (_T ("]LOG]!>"));

		WriteString (_T ("<time="));	
		WriteString (t.Format (_T ("\"%H:%M:%S.000")));	
		strTemp.Format (_T("+%d\""), m_tzOffset/60);
		WriteString (strTemp);	
		
		WriteString (_T (" date="));	
		WriteString (t.Format (_T ("\"%m-%d-%Y\"")));

		WriteString (_T (" component="));
		WriteString (_T ("\""));
		WriteString (m_strComponent);	
		WriteString (_T ("\""));

		WriteString (_T (" context="));	
		WriteString (_T ("\"\""));

		WriteString (_T (" type="));	
		strTemp.Format (_T("\"%d\""), type);
		WriteString (strTemp);	

		WriteString (_T (" thread="));	
		strTemp.Format (_T("\"%d\""), nThreadID);
		WriteString (strTemp);	

		WriteString (_T (" file="));
		strTemp = lpszFile;
		int lastslash = strTemp.ReverseFind ( _T('\\')) + 1;
		//Strip the path so that only the filename is written to the log
		strTemp.Format (_T("\"%s:%d\""), strTemp.Right (strTemp.GetLength ()- lastslash), nLineNum);
		WriteString (strTemp);	

		WriteString (_T (">\n"));
	}

}
